import time
import traceback

from docx.shared import Pt
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.enum.section import WD_ORIENTATION
from docx import Document
from docx.shared import Pt,Inches, Cm, RGBColor
from docx.oxml.ns import qn
import datetime
# 创建一个新的Word文档
import docx
from pdf2image import convert_from_path
import fitz
from io import BytesIO
from PIL import ImageOps
from bid.generate.models import ExFile, ExBid, ExBidCatalog
from zentao.settings import ROOT_FOLDER


#业绩生成
def generate_project(data_dict, extra_data, save_path, bid_id):

    doc = Document()

    #序号
    title_id = '99.'
    # title_id = ''

    #第一节转为横向
    default_section = doc.sections[0]
    default_section.orientation = WD_ORIENTATION.LANDSCAPE  # 改为横向
    # 需要手动互换高度和宽带
    default_section.page_width, default_section.page_height = default_section.page_height, default_section.page_width

    # 定义标题和正文的样式
    # title0="（十四）近年完成的类似项目情况"
    title0="（九十九）近年完成的类似项目情况"
    project_count = len(data_dict)
    total_amount = extra_data['total_amount']

    # 构建内容字符串
    content0 = f"我公司具有丰富的信息化项目建设相关业绩，共提供近年完成的同类项目业绩共 {project_count} 个，业绩总金额为：{total_amount} 万元。"


    styles = [
        (title0, content0, 15.5, True, WD_PARAGRAPH_ALIGNMENT.CENTER, 14, False, WD_PARAGRAPH_ALIGNMENT.LEFT, 1)
    ]

    # new_style = (title1, content1, 16, True, WD_PARAGRAPH_ALIGNMENT.CENTER, 12, False, WD_PARAGRAPH_ALIGNMENT.JUSTIFY)
    # styles.append(new_style)

    # 添加标题和正文到文档中
    for style in styles:
        title, content, title_font_size, title_bold, title_alignment, content_font_size, content_bold, content_alignment, level = style

        # 添加标题
        paragraph = doc.add_heading(level=level)
        run = paragraph.add_run(title)
        run.font.color.rgb = RGBColor(0, 0, 0)  # 设置颜色为黑色
        run.font.italic = False  # 关闭斜体
        run.font.size = Pt(title_font_size)
        run.bold = title_bold
        # 设置字体为宋体
        run.font.name = 'SimSun'  # 英文名'SimSun'对应宋体
        run._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')  # 确保中文字符使用宋体
        paragraph.alignment = title_alignment
        paragraph.paragraph_format.line_spacing = 1.5
        # paragraph.paragraph_format.first_line_indent = Cm(1) #悬挂缩进1cm
        paragraph.paragraph_format.space_before = Pt(5)  # 设置段前间距为5磅
        # paragraph.paragraph_format.space_after = Pt(5)  # 设置段后间距为5磅


        # 添加正文
        if content is not None:
            paragraph = doc.add_paragraph()
            run = paragraph.add_run(content)
            run.font.size = Pt(content_font_size)
            run.bold = content_bold
            # 设置字体为宋体
            run.font.name = 'SimSun'  # 英文名'SimSun'对应宋体
            run._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')  # 确保中文字符使用宋体
            paragraph.alignment = content_alignment
            paragraph.paragraph_format.line_spacing = 1.5  # 设置行间距为1.5倍
            paragraph.paragraph_format.first_line_indent = Pt(24)  # 设置首行缩进为2个字符（大约24磅）
            paragraph.paragraph_format.space_before = Pt(13)  # 设置段前间距为13磅

            # 设置段落的左边缩进为2cm，右边缩进为1cm
            # paragraph.paragraph_format.left_indent = Cm(2)
            # paragraph.paragraph_format.right_indent = Cm(1)

        #添加表格数据

        table = doc.add_table(rows= len(data_dict) + 1, cols=8)

        #设置表格左缩进
        table.left_indent = Cm(2)  # 设置表格左缩进

        #设置表格列宽
        # col_width_dic = {0: 1.29, 1: 5.09, 2: 1.49, 3: 2.93, 4: 3.16, 5: 2.45, 6: 7.37, 7: 1.92}
        col_widths = [1.29, 5.09, 1.49, 2.93, 3.16, 2.45, 7.37, 1.92]
        # for col_num in range(8):
        #     table.cell(0, col_num).width = Cm(col_width_dic[col_num])
        # 应用每列的宽度
        for col, width in zip(table.columns, col_widths):
            for cell in col.cells:
                cell.width = Cm(width)

        # 设置表格样式以显示框线
        table.style = 'Table Grid'
        headers = ["序号","项目名称","项目地点","合同(服务)对方名称","对方联系人及电话","合同金额(万元)","项目描述","备注"]

        # 填写表头
        for i, header in enumerate(headers):
            cell = table.cell(0, i)
            cell.text = header
            for paragraph in cell.paragraphs:
                for run in paragraph.runs:
                    run.bold = True  # 设置表头文本加粗
                    run.font.size = Pt(12)  # 设置字体为小四号
                    run.font.name = '宋体'
                    run._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')


        def set_cell_font(cell, text):
            cell.text = text
            for paragraph in cell.paragraphs:
                for run in paragraph.runs:
                    run.font.size = Pt(12)  # 设置字体为小四号
                    run.font.name = '宋体'
                    run._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')


        def table_wr(i):
            # 填写内容
            row = table.rows[i + 1]  # 第二行用于填写内容
            for ind_j,j in enumerate(headers):
                if j=="序号":
                    set_cell_font(row.cells[0], str(i + 1))  # 序号
                else:
                    set_cell_font(row.cells[ind_j], str(data_dict[i][j]))

        for i in range(len(data_dict)):
            table_wr(i)

    #添加分节符
    doc.add_section()

    # 第二节转为竖向
    default_section = doc.sections[1]
    default_section.orientation = WD_ORIENTATION.LANDSCAPE  # 改为横向
    # 需要手动互换高度和宽带
    default_section.page_width, default_section.page_height = default_section.page_height, default_section.page_width

    # 14.1.客户服务平台 (营商环境优化配套支撑个性化业务组件及 应用) 建设项目
    # 14.1.1.中标通知书
    # 14.1.2.合同扫描件
    # 14.1.3.合同转签协议
    # 14.1.4.验收证书

    #图片插入
    # 添加截图信息
    def image_write(data):
        paragraph = doc.add_paragraph()
        # 在段落中添加图片
        # 假设图片文件名为'image.png'，位于当前目录下
        image_path = data
        run = paragraph.add_run()
        # 一直插图片
        judge = False
        while not judge:
            try:
                run.add_picture(image_path, width=Inches(6))  # 设置图片宽度为4英寸
                judge = True
            except:
                print(traceback.format_exc())
                print(image_path)
        paragraph.alignment = 1

    # 图片裁剪
    def trim_and_add_border(image):
        # 将图片转换为灰度图像，便于处理
        grayscale_image = image.convert('L')

        width = grayscale_image.width
        height = grayscale_image.height

        # 找到需要裁剪的边界
        def find_borders(img):
            invert_img = ImageOps.invert(img)
            bbox = invert_img.getbbox()
            return bbox

        borders = find_borders(grayscale_image)

        if not borders:
            borders = (0, 0, width, height)
        else:
            left, top, right, bottom = borders
            left = max(0, left - width // 20)
            right = min(width, right + width // 20)
            top = max(0, top - height // 20)
            bottom = min(height, bottom + height // 20)

            if (bottom - top) / (right - left) > 1.414:
                new_width = int((bottom - top) / 1.415)
                left = min(left, max(0, (width - new_width) // 2))
                right = max(right, min(width, new_width + (width - new_width) // 2))

                # print((bottom - top) / (right - left))

            borders = (left, top, right, bottom)
        # print(borders)
        trimmed_image = image.crop(borders)

        return trimmed_image

    def pdf_image(pdf_path):
        # st = time.time()
        images = convert_from_path(pdf_path)
        # 遍历所有图片并将其添加到Word文档中
        for image in images:
            image = trim_and_add_border(image)
            # image.save('/media/977GB/wcj_work/投标文件生成/团队生成.png')
            # 保存图片到临时文件
            temp_image_path = 'temp_image.png'
            image.save(temp_image_path, 'JPEG')

            # 将图片添加到Word文档
            # doc.add_picture(temp_image_path, width=Inches(6))  # 设置插入的图片大小为6英寸
            # 在文档中添加一个新的段落
            paragraph = doc.add_paragraph()

            # 设置段落的对齐方式为居中
            paragraph.alignment = 1  # 1代表居中对齐

            # 创建一个运行并添加图片
            run = paragraph.add_run()
            # 一直插图片
            judge = False
            while not judge:
                try:
                    run.add_picture(temp_image_path, width=Inches(6))  # 设置插入的图片大小为6英寸
                    judge = True
                except:
                    traceback.format_exc()
        # print(time.time() - st)
    # def pdf_image(pdf_path):
    #     st = time.time()
    #     # images = convert_from_path(pdf_path,dpi=100)
    #     # # 遍历所有图片并将其添加到Word文档中
    #     # for image in images:
    #     #     # image.save('/media/977GB/wcj_work/投标文件生成/团队生成.jpg')
    #     #     # 保存图片到临时文件
    #     #     temp_image_path = 'temp_image.jpg'
    #     #     image.save(temp_image_path, 'JPEG')
    #     #
    #     #     # 将图片添加到Word文档
    #     #     doc.add_picture(temp_image_path, width=Inches(6))  # 设置插入的图片大小为6英寸
    #     # 打开PDF文件
    #     pdf_document = fitz.open(pdf_path)
    #     total_pages = pdf_document.page_count
    #
    #     for page_num in range(total_pages):
    #         # 获取单页
    #         page = pdf_document.load_page(page_num)
    #
    #         # 将页面转换为图像
    #         pix = page.get_pixmap(matrix=fitz.Matrix(1.389, 1.389))
    #         # pix.save('/media/977GB/wcj_work/投标文件生成/团队生成1.png')
    #
    #         # 使用BytesIO创建内存中的字节流
    #         img_stream = BytesIO(pix.tobytes("png"))  # 直接从Pixmap获取PNG格式的字节流
    #
    #         # import numpy as np
    #         # st = time.time()
    #         # img_array = np.frombuffer(pix.samples, dtype=np.uint8).reshape(pix.height, pix.width, 3)
    #         # print(11, time.time() - st)
    #
    #         # 将图像添加到Word文档中
    #         # doc.add_paragraph(f"Page {page_num + 1}")
    #         doc.add_picture(img_stream, width=Inches(6))  # 调整图像大小以适应页面
    #     print(time.time() - st)

    for i in range(len(data_dict)):
        # title="14."+str(i+1)+data_dict[i]["项目名称"]
        title=title_id+str(i+1)+data_dict[i]["项目名称"]
        # t_content=["中标通知书","合同扫描件","合同转签协议","验收证书"]
        t_content=list(data_dict[i].keys())[8:]
        content=None
        styles=[(title, content, 14.5, True, WD_PARAGRAPH_ALIGNMENT.LEFT, 12, False, WD_PARAGRAPH_ALIGNMENT.LEFT, 2)]
        for index,t_c in enumerate(t_content):
            # title_name="14."+str(i+1)+"."+str(index+1)+str(t_c)
            title_name=title_id+str(i+1)+"."+str(index+1)+str(t_c)
            content=None
            sty=(title_name, content, 14, True, WD_PARAGRAPH_ALIGNMENT.LEFT, 12, False, WD_PARAGRAPH_ALIGNMENT.JUSTIFY,3)
            styles.append(sty)
        for style in styles:
            title, content, title_font_size, title_bold, title_alignment, content_font_size, content_bold, content_alignment, level = style

            # 添加标题
            paragraph = doc.add_heading(level=level)
            run = paragraph.add_run(title)
            run.font.color.rgb = RGBColor(0, 0, 0)  # 设置颜色为黑色
            run.font.italic = False  # 关闭斜体
            run.font.size = Pt(title_font_size)
            run.bold = title_bold
            paragraph.alignment = title_alignment
            # 设置字体为宋体
            run.font.name = 'SimSun'  # 英文名'SimSun'对应宋体
            run._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')  # 确保中文字符使用宋体
            paragraph.paragraph_format.line_spacing = 1.5

            # 悬挂缩进1cm
            paragraph.paragraph_format.left_indent = Cm(1.21)
            paragraph.paragraph_format.first_line_indent = Cm(-1.21)

            paragraph.paragraph_format.space_before = Pt(5)  # 设置段前间距为5磅
            # paragraph.paragraph_format.space_after = Pt(5)  # 设置段后间距为5磅
            for tem_c in t_content:
                if tem_c in title:

                    #"中标通知书","合同扫描件","合同转签协议","验收证书"
                    _c=data_dict[i][tem_c]
                    if _c.endswith('.pdf'):
                        pdf_image(_c)
                    else:
                        image_write(_c)

    #修改页边距
    # print(len(doc.sections))
    for i in range(len(doc.sections)):
        doc.sections[i].top_margin = Cm(0.71)
        doc.sections[i].bottom_margin = Cm(0.71)
        doc.sections[i].left_margin = Cm(2.35)
        doc.sections[i].right_margin = Cm(2.35)

    # 保存文档的路径
    current_time = datetime.datetime.now()
    filename = current_time.strftime(save_path)
    # 保存文档的路径
    filepath_modified = filename
    doc.save(filepath_modified)

    # 将文件添加到文件数据库表中
    file = ExFile.objects.create(
        path=filepath_modified.replace(ROOT_FOLDER, ''),
        type='docx',
        comment='',
        uploadDate=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
    )

    # 更新数据库
    ExBid.objects.filter(id=bid_id).update(project=file)


